import os
import pytest
import time
from py._xmlgen import html
from appium import webdriver
from base import config
from util.user_log import log
import warnings

warnings.simplefilter("ignore", ResourceWarning)

report_dir = config.file_dir.dir_report
devices = config.devices
app = config.file_dir.dir_apk
package = config.package
activity = config.activity
implicitly_wait = config.implicitly_wait


# 启动appium
@pytest.fixture(scope='session', autouse=True)
def browser():
    global driver
    desired_caps = {
        'platformName': 'Android',
        # 'platformVersion': '7.0',       # 安卓版本号可以不写
        'deviceName': devices,  # 设备名，或者设备的ip地址
        # 'app': app,
        'appPackage': package,  # app的包名
        'appActivity': activity,  # 启动名
        # 'appWaitActivity': activity,
        # 'appWaitDuration': 20000,
        'automationName': 'Uiautomator2',  # 设置测试引擎，默认是appium
        'unicodeKeyboard': True,  # 可以输入中文
        'resetKeyboard': True,  # 测试结束后，输入法重置到原来状态
        'noReset': True,  # 设置为非初始启动（跳过新手引导）
        # 在电脑端的chrome上连接微信公众号
        # 'chromeOptions': {'androidProcess': 'com.tencent.mm:tools'}
    }
    params = config.appium_address, config.appium_port01
    driver = webdriver.Remote('http://{}:{}/wd/hub'.format(*params), desired_caps)
    # 等主页面activity出现
    # driver.wait_activity(activity, 5)
    driver.implicitly_wait(implicitly_wait)
    driver.keyevent(3)  # home键
    return driver


# 写入cookie
@pytest.fixture(scope="session", autouse=True)
def check_cookie():
    # 待补充
    pass


# 关闭浏览器
@pytest.fixture(scope="session", autouse=True)
def browser_quit():
    yield driver
    log.info('退出driver')
    driver.quit()
    print("test end!")


# 修改html中的Environment部分
def pytest_configure(config):
    config._metadata['测试环境'] = '外网环境'


# 修改html中的Summary部分
@pytest.mark.optionalhook
def pytest_html_results_summary(prefix, summary, postfix):
    prefix.extend([html.p("测试人: 听风")])


# 设置用例描述表头
@pytest.mark.optionalhook
def pytest_html_results_table_header(cells):
    cells.pop(1)
    cells.insert(1, html.th('用例标题'))
    cells.insert(2, html.th('用例描述'))
    cells.insert(3, html.th('运行时间', class_='sortable time', col='time'))


# 设置用例描述表格
@pytest.mark.optionalhook
def pytest_html_results_table_row(report, cells):
    cells.pop(1)
    cells.insert(1, html.td(report.nodeid))
    cells.insert(2, html.td(report.description))
    cells.insert(3, html.td(time.strftime("%Y-%m-%d %H:%M:%S"), class_='col-time'))
    cells.insert(4, html.td(report.duration))


@pytest.mark.hookwrapper
def pytest_runtest_makereport(item):
    """
    用于向测试用例中添加用例的开始时间、内部注释，和失败截图等.
    """
    pytest_html = item.config.pluginmanager.getplugin('html')
    outcome = yield
    report = outcome.get_result()
    # 设置编码显示中文
    report.nodeid = report.nodeid.encode("utf-8").decode("unicode_escape")
    report.description = config_main.description_html(item.function.__doc__)
    extra = getattr(report, 'extra', [])
    report.extra = extra
    if report.when == 'call' or report.when == "setup":
        xfail = hasattr(report, 'wasxfail')
        if (report.skipped and xfail) or (report.failed and not xfail):
            case_path = report.nodeid.replace("::", "_") + ".png"
            if "[" in case_path:
                case_name = case_path.split("-")[0] + "].png"
            else:
                case_name = case_path
            config_main.capture_screenshot(case_name)
            img_path = "image/" + case_name.split("/")[-1]
            log.debug('截图路径：{}'.format(img_path))
            if img_path:
                html = '<div><img src="%s" alt="screenshot" style="width:304px;height:228px;" ' \
                       'onclick="window.open(this.src)" align="right"/></div>' % img_path
                extra.append(pytest_html.extras.html(html))


class ConfigMain:
    @staticmethod
    def description_html(desc):
        """
        将用例中的描述转成HTML对象
        :param desc: 描述
        :return:
        """
        if desc is None:
            desc = ' 【描述】'
            # return "No case description"
        desc_ = ""
        for i in range(len(desc)):
            if i == 0:
                pass
            elif desc[i] == '\n':
                desc_ = desc_ + ";"
            else:
                desc_ = desc_ + desc[i]

        desc_lines = desc_.split(";")
        desc_html = html.html(
            html.head(
                html.meta(name="Content-Type", value="text/html; charset=latin1")),
            html.body(
                [html.p(line) for line in desc_lines]))
        return desc_html

    @classmethod
    def capture_screenshot(cls, case_name):
        """
        配置用例失败截图路径
        :param case_name: 用例名
        :return:
        """
        # global driver
        file_name = case_name.split("/")[-1]
        # print(file_name)
        new_report_dir = cls.new_report_time()
        if new_report_dir is None:
            raise RuntimeError('没有初始化测试目录')
        image_dir = os.path.join(report_dir, new_report_dir, "image", file_name)
        # print('截图目录：',image_dir)
        log.debug('截图目录：%s' % image_dir)
        try:
            driver.get_screenshot_as_file(image_dir)
        except:
            log.debug('截图失败')
            # raise MyError('异常：截图失败')

    @classmethod
    def new_report_time(cls):
        """
        获取最新报告的目录名（即运行时间，例如：2018_11_21_17_40_44）
        """
        files = os.listdir(report_dir)
        files.sort()
        try:
            return files[-1]
        except IndexError:
            return None


config_main = ConfigMain

if __name__ == "__main__":
    pass
    # a01 = new_report_time()
    # print(a01)
    # capture_screenshot("test_dir/test_baidu_search.test_search_python.png")
    # print(report_dir)
    # 在conftest.py文件中抛出异常，会导致整个会话中断；尽量不要抛异常
